// 负责 统一封装 axios
import axios from 'axios'
// 导入 vuex 仓库
import store from '@/store/index.js'
// 导入 更新token 方法
import { getNewToken } from '@/api/user.js'

// 1.设置 基地址 (简化 和 复用 基地址)
const axios1 = axios.create({
    // 设置 当前 axios对象的 基地址
    baseURL: 'http://toutiao.itheima.net'
})

// 2.设置 拦截器（请求拦截器 和 响应拦截器）
// 每当 axios 发送请求 之前，会先执行一次，然后 再生成请求报文 发给服务器
// conf：是本次 axios请求的 配置信息 对象，包含程序员传入的信息
axios1.interceptors.request.use(function (conf) {
    // 如果 仓库中 存在 token
    if (!conf.headers.Authorization && store.state.user && store.state.user.token) {
        // 在发送请求之前，为 请求报文头 追加 token
        conf.headers.Authorization = 'Bearer ' + store.state.user.token
    }
    return conf
})

// 3.设置 响应拦截器
axios1.interceptors.response.use(function (conf) {
    // console.log('响应拦截器->', conf)
    return conf
}, async function (err) {
    // 如果 响应状态码 为401，说明 未登录 或 token失效
    if (err.response.status === 401) {
        // ?. 如果前面为null/undefined，则直接返回 undefeind
        //    如果    不为空，则 返回调用的属性值
        // 如果 仓库里的token不为空，则说明是 token失效，需要从新请求token
        if (store.state.user?.token) {
            try {
                const refreshToken = store.state.user?.refresh_token
                // a.请求新token 
                const { data: resBody } = await getNewToken(refreshToken)
                console.log(resBody.data.token)
                // b.将 新token 保存到 仓库的 token中
                // c.将 新token 保存到 localStorage
                const tokenPair = store.state.user
                tokenPair.token = resBody.data.token
                store.commit('setUserToken', tokenPair)
                // d.将 上次请求的配置信息的 token 更新成 新 token
                err.config.headers.Authorization = 'Bearer ' + resBody.data.token
                // d.重新执行 上一次失败的 axios请求
                return axios1(err.config)
            } catch (err) {
                // 如果 连 refresh_token都失效了，则需要重新登录
                if (err.response.data.message == 'refresh_token失效') {
                    window.location.hash = '/login'
                }
            }
        }
    }


    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(err);
})

// 默认导出
export default axios1